<template>
  <div class="container">
    <div class="search">
      <el-input v-model="params.name" placeholder="请输入歌曲名" clearable></el-input>
      <el-select v-model="params.singerId" placeholder="歌手">
        <el-option v-for="item in singerData" :key="item.id" :value="item.id" :label="item.name"></el-option>
      </el-select>
      <el-input v-model="params.other" placeholder="模糊查询" clearable></el-input>
      <el-select v-model="params.status" placeholder="歌手状态" clearable>
        <el-option value="0" label="正常"></el-option>
        <el-option value="1" label="封禁"></el-option>
      </el-select>
      <el-button type="primary" @click="findBySearch">搜索</el-button>
      <el-button type="warning" @click="clearParams">清空</el-button>
      <el-button type="success" @click="addSong">新增</el-button>
      <el-button type="danger" @click="delBatch">批量删除</el-button>
      <el-button type="info" @click="cancelSelecte">取消选择</el-button>
      <el-button type="success" @click="exportReport">导出报表</el-button>
      <el-button type="primary" @click="importBatch">批量导入</el-button>
    </div>

    <div class="table">
      <el-table :data="songData" ref="tableRef" stripe highlight-current-row style="width: 100%" height="75vh"
        :row-key="getRowKeys" @selection-change="handleSelectionChange">
        <el-table-column fixed type="selection" :reserve-selection="true"></el-table-column>
        <el-table-column fixed label="序号" prop="id" sortable width="80" align="center"></el-table-column>
        <el-table-column fixed label="歌手" prop="singerName" width="70">
          <template #default="{row}">
            {{ row.singerName.split('-').length !== 1 ? row.singerName.split('-')[0] : row.singerName }}
          </template>
        </el-table-column>
        <el-table-column fixed label="歌曲名" prop="name" width="100" align="center">
          <template #default="{ row }">{{ row.name.split('-').length !== 1 ? row.name.split('-')[1] : row.name
            }}</template>
        </el-table-column>
        <el-table-column label="介绍" prop="introduction" width="130" align="center"></el-table-column>
        <el-table-column label="歌曲封面" prop="pic" width="100" align="center">
          <template #default="{ row }">
            <el-image style="width: 70px; height: 70px; border-radius: 50%"
              :src="'http://localhost:8080/api/files/' + row.pic"
              :preview-src-list="['http://localhost:8080/api/files/' + row.pic]"></el-image>
          </template>
        </el-table-column>

        <el-table-column label="歌曲" prop="url" width="350" align="center">
          <template #default="{ row }">
            <div v-if="row.url != null && row.url !==''">
              <audio v-if="row.url.includes('song|')" :src="'http://localhost:8080/api/files/' + row.url"
                controls></audio>
              <audio v-else :src="row.url" controls>
                <source :src="row.url">
                您的浏览器不支持 audio 标签。
              </audio>
            </div>
            <div v-else>暂无歌曲</div>
          </template>
        </el-table-column>

        <!-- <el-table-column label="歌词" prop="lyric" width="350" align="center"></el-table-column> -->
        <el-table-column label="歌词" prop="lyric" width="350" align="center">
          <template #default="{ row }">
            <div class="multiline-ellipsis">
              {{ row.lyric }}
            </div>
          </template>
        </el-table-column>
        <el-table-column label="歌单操作" width="90">
          <template #default="{ row }">
            <el-button type="primary" @click="editSongList(row)">编辑</el-button>
          </template>
        </el-table-column>
        <el-table-column prop="clicks" label="点击次数" width="130" sortable align="center"></el-table-column>
        <el-table-column prop="createTime" label="创建日期" width="150"></el-table-column>
        <el-table-column prop="updateTime" label="更新日期" width="150"></el-table-column>

        <el-table-column fixed="right" label="账号状态" prop="status" width="80">
          <template #default="{ row }">
            <el-switch v-model="row.sts" @change="updateStatus(row)"></el-switch>
          </template>
        </el-table-column>
        <el-table-column fixed="right" label="操作" width="150" align="center">
          <template #default="{ row }">
            <div style="margin-bottom: 5px">
              <el-button type="primary" size="small" @click="editSong(row)">编辑</el-button>

              <el-dropdown trigger="hover" style="margin-left: 10px;">
                <el-button type="success" size="small">
                  下载 &nbsp;<i-ep-arrow-down />
                </el-button>
                <template #dropdown>
                  <el-dropdown-menu>
                    <el-dropdown-item :disabled="!row.pic" @click="downLoadPic(row)">图片</el-dropdown-item>
                    <el-dropdown-item :disabled="!row.url" @click="downLoadUrl(row)">音频</el-dropdown-item>
                  </el-dropdown-menu>
                </template>
              </el-dropdown>
            </div>
            <div>
              <el-popconfirm title="你确定删除吗？" confirm-button-text="确定" cancel-button-text="取消"
                @confirm="deleteSong(row)">
                <template #reference>
                  <el-button type="danger" size="small">删除</el-button>
                </template>
              </el-popconfirm>
              <el-dropdown trigger="hover" style="margin-left: 10px;">
                <el-button type="info" size="small">
                  详情 &nbsp;<i-ep-arrow-down />
                </el-button>
                <template #dropdown>
                  <el-dropdown-menu>
                    <el-dropdown-item @click="detailBing(row)">Bing</el-dropdown-item>
                    <el-dropdown-item @click="detailMusic(row)">Music</el-dropdown-item>
                  </el-dropdown-menu>
                </template>
              </el-dropdown>
            </div>
          </template>
        </el-table-column>
      </el-table>
    </div>

    <div class="pagination">
      <el-pagination v-model:current-page="params.pageNum" v-model:page-size="params.pageSize"
        :page-sizes="[5, 10, 15, 20]" size="default" layout="total, sizes, prev, pager, next, jumper"
        :total="params.total" @size-change="findBySearch" @current-change="findBySearch" />
    </div>

    <div class="dialog">
      <!-- 新增or编辑弹窗 -->
      <el-dialog v-model="dialogFormVisible" :title="(dialogFormData.id || dialogFormData.id === 0) ? '修改信息' : '添加歌曲'"
        width="50%" top="3vh" @close="cancel" align="center">
        <el-form :model="dialogFormData">
          <el-form-item label="歌曲名" label-width="20%">
            <el-input v-model="dialogFormData.name" clearable></el-input>
          </el-form-item>
          <el-form-item label="歌手" label-width="20%">
            <el-select v-model="dialogFormData.singerId" placeholder="请选择">
              <el-option v-for="item in singerData" :key="item.id" :label="item.name" :value="item.id"></el-option>
            </el-select>
          </el-form-item>

          <!-- 头像上传 -->
          <el-form-item label="歌曲封面" label-width="20%">
            <el-upload action="http://localhost:8080/api/files/upload?fileDir=songPic" list-type="picture-card"
              :auto-upload="true" :limit="1" :on-success="successUpload" :on-remove="handleRemove"
              :on-preview="handlePicturePreview" :file-list="picList" :class="{ 'none-up': uploadDisabled }">
              <i-ep-plus />
            </el-upload>
          </el-form-item>

          <el-form-item label="歌曲" label-width="20%" style="position: relative;">
            <el-upload action="http://localhost:8080/api/files/upload?fileDir=song" list-type="stringtext"
              :on-success="successSongUpload" :on-remove="handleSongRemove" :file-list="songList" :limit="1"
              :on-exceed="handleSongExceed" style="width: 90%;">
              <el-button type="primary" style="position: absolute;left: 5%;top: -2%;">点击上传</el-button>
            </el-upload>
            <div style="position: absolute;left: 30%;top: -3%;">
              <el-button type="warning" :disabled="(songList.length !== 0)"
                @click="songUrlVisible = true">上传网络地址</el-button>
              <el-button type="info" style="margin-left: 50px;"
                @click="songList = [], dialogFormData.url = ''">清空</el-button>
            </div>
          </el-form-item>

          <el-form-item label="介绍" label-width="20%">
            <el-input v-model="dialogFormData.introduction" style="width: 90%" type="textarea" rows="3"></el-input>
          </el-form-item>
          <el-form-item label="歌词" label-width="20%">
            <el-input v-model="dialogFormData.lyric" style="width: 90%" type="textarea" rows="5"></el-input>
            <div style="margin-top: 7px;">
              <el-button type="success" @click="autoLyric">自动检索歌词</el-button>
              <el-button type="warning" @click="selfLyric">手动检索歌词</el-button>
            </div>
          </el-form-item>
          <el-form-item prop="clicks" label="点击次数" label-width="20%">
            <el-input v-model="dialogFormData.clicks" style="width: 90%" clearable></el-input>
          </el-form-item>
        </el-form>
        <template #footer>
          <div class="dialog-footer">
            <el-button @click="cancel">取消</el-button>
            <el-button type="primary" @click="submit"> 确定 </el-button>
          </div>
        </template>
      </el-dialog>
      <!-- 头像预览弹窗 -->
      <el-dialog v-model="preImgVisible" width="600" align-center>
        <img :src="'http://localhost:8080/api/files/' + dialogFormData.pic" alt="头像预览" style="width: 100%" />
      </el-dialog>
      <!-- 歌曲网络地址弹窗 -->
      <el-dialog v-model="songUrlVisible" width="500" title="输入歌曲的网络地址" align-center @close="dialogFormData.url = ''">
        <el-input v-model="dialogFormData.url"></el-input>
        <template #footer>
          <div class="dialog-footer">
            <el-button @click="songUrlVisible = false, dialogFormData.url = ''">取消</el-button>
            <el-button type="primary"
              @click="(songList = dialogFormData.url ? [{ name: dialogFormData.url }] : []), songUrlVisible = false">确定</el-button>
          </div>
        </template>
      </el-dialog>
      <!-- 歌单操作弹窗 -->
      <el-dialog v-model="songListVisible" title="选择添加的歌单" width="30%" align-center @close="">
        <el-form :model="songListFormData">
          <el-form-item label="歌曲名" label-width="20%">
            <el-tag type="success">{{ songListFormData.songName }}</el-tag>
          </el-form-item>
          <el-form-item label="现有歌单" label-width="20%">
            <div v-if="songListFormData.songListNames.length === 0"><el-tag type="danger">暂无歌单</el-tag></div>
            <div v-else>
              <el-tag type="primary" @close="removeSongList(item)" @click="songListSongDetail(item)" v-for="item in songListFormData.songListNames"
                :key="item.id" closable>{{ item.title }}</el-tag>
            </div>
          </el-form-item>
          <el-form-item label="歌单" label-width="20%">
            <el-select v-model="songListFormData.songListId" placeholder="请选择" style="width: 90%;" clearable>
              <el-option v-for="item in songListAll" :key="item.id" :label="item.titles" :value="item.id"></el-option>
            </el-select>
          </el-form-item>
        </el-form>
        <template #footer>
          <div class="dialog-footer">
            <el-button @click="songListVisible=false">关闭</el-button>
            <el-button type="primary" @click="songListSubmit">添加</el-button>
          </div>
        </template>
      </el-dialog>
    </div>
  </div>
</template>

<script setup lang="ts">
import { listSongDeleteApi, listSongSaveApi } from '@/api/listSong'
import { singerFindAllApi } from '@/api/singer'
import { songDelBatchApi, songDeleteApi, songFindAllApi, songFindBySearchApi, songFindLyricApi, songSaveApi } from '@/api/song'
import { songListFindAllApi, songListFindBySongIdApi } from '@/api/songList'
import router from '@/router'
import { ElMessage, ElMessageBox } from 'element-plus'
import { onMounted, ref } from 'vue'

// 搜索框数据
const params = ref({
  singerId:null,
  name:null,
  other:null,
  status:null,
  total:null,
  pageNum:1,
  pageSize:5
})
// 新增or修改弹窗数据
const dialogFormData: any = ref({
  id: '',
  name: '',
  singerId: '',
  pic: '',
  url: '',
  introduction: '',
  lyric: '',
  clicks: '',
  cont: 0//0:正常添加，若有重复则报异常；1：强制添加
})
// 歌单弹窗数据
const songListFormData:any = ref({
  songName:'',
  songListNames:[],//当前歌曲现有的歌单合集
  songId:'',
  songListId:''
})

// 表单对象
const tableRef:any = ref()

// 歌曲信息【当前页】
const songData = ref()
// 所有歌手信息
const singerData = ref<any>([])
// 所有歌曲信息
const songDataAll = ref<any>([])
// 所有歌单信息
const songListAll = ref<any>([])

// 控制弹窗的显示与隐藏
const dialogFormVisible = ref(false)
// 控制图像预览
const preImgVisible = ref(false)
// 控制歌曲网络地址的弹窗
const songUrlVisible = ref(false)
// 控制歌单操作弹窗
const songListVisible = ref(false)

// 上传头像列表
const picList = ref<any>([])
// 上传歌曲列表
const songList = ref<any>([])
// table中选中的选项列表
const selecteList = ref<any>([])

// 上传动态类
const uploadDisabled = ref(false)

onMounted(() => {
  findBySearch()
  findSingerAll()
  findSongAll()
  findSongListAll()
})
// 搭配table=>type=selection的获取行：行数据的 Key，用来优化 Table 的渲染
const getRowKeys = (row: any) => {
  return row.id
}
// 搜索所有歌手信息
const findSingerAll = async () => {
  let res = await singerFindAllApi()
  singerData.value = res.data
}
// 搜索所有歌曲信息
const findSongAll = async () => {
  let res = await songFindAllApi()
  songDataAll.value = res.data
}
// 搜索所有歌单信息
const findSongListAll = async ()=>{
  let res = await songListFindAllApi()
  songListAll.value = res.data.map((item:any)=>({
    ...item,
    titles:item.title?.length > 10 ? item.title.substring(0,10) + '...' : item.title
  }))
}
// 搜索
const findBySearch = async () => {
  let res = await songFindBySearchApi(params.value)
  // 因为v-model:的值必须是一个数据属性或响应式引用
  songData.value = res.data.list.map((item: any) => ({
    ...item,
    sts: item.status === '0'
  }))
  params.value.total = res.data.total
}
// 清空
const clearParams = () => {
  params.value = {
    singerId: null,
    name: null,
    other: null,
    status: null,
    total: null,
    pageNum: 1,
    pageSize: 5
  }
  findBySearch()
}
// 新增
const addSong = () => {
  dialogFormVisible.value = true
  uploadDisabled.value = false
  // 清除表单信息
  dialogFormData.value = {
    id: '',
    name: '',
    singerId: '',
    pic: '',
    url: '',
    introduction: '',
    lyric: '',
    clicks: '',
    cont: 0
  }
}
// 编辑
const editSong = (row: any) => {
  console.log('编辑row:',row)
  picList.value = []
  songList.value = []
  dialogFormVisible.value = true
  // dialogFormData.value = row//这里这样赋值会丢失cont值
  Object.assign(dialogFormData.value,row)
  if (row.pic) {
    picList.value.push({ name: row.pic, url: 'http://localhost:8080/api/files/' + row.pic })
  }
  if (row.url) {
    songList.value.push({ name: row.url, url: 'http://localhost:8080/api/files/' + row.url })
  }
  uploadDisabled.value = picList.value.length >= 1
}
// 下载图片
const downLoadPic = (row: any) => {
  if (row.pic.includes('|')) {
    location.href = 'http://localhost:8080/api/files/' + row.pic
  } else {
    ElMessage.warning('无可下载资源')
  }
}
// 下载音频
const downLoadUrl = (row:any) => {
  if(row.url.includes('|')){
    location.href = 'http://localhost:8080/api/files/'+row.url
  }else if(row.url.includes('http')){
    location.href = row.url
  }else {
    ElMessage.warning('无可下载资源')
  }
}
// 删除
const deleteSong = async (row: any) => {
  await songDeleteApi(row.id)
  findBySearch()
  ElMessage.success('删除成功')
}
// 网页bing详情
const detailBing = (row: any) => {
  window.open('https://cn.bing.com/search?q=' + row.name, '_blank')
}
// 前台Music详情【TODO】
const detailMusic = (row:any)=>{
  // window.open('http://localhost:163/?name='+row.name+'&type=netease','_blank')
  ElMessage.warning('该功能还未开发，敬请期待')
}
// 头像上传成功
const successUpload = (res: any, file: any, fileList: any) => {
  // console.log('res',res)
  // console.log('file',file)
  // console.log('fileList',fileList)
  picList.value = fileList
  uploadDisabled.value = picList.value.length >= 1
  dialogFormData.value.pic = res.data
}
// 歌曲上传成功
const successSongUpload = (res: any, file: any, fileList: any) => {
  songList.value = fileList
  dialogFormData.value.url = res.data
}
// 歌曲上传超过limit时覆盖掉前一个
const handleSongExceed = (files: File[]) => {
  songList.value = files
  // console.log(files)   files:是超过limit之后上传的文件数组【一个或多个，这里是一个】
}
// 删除头像
const handleRemove = (file: any, fileList: any) => {
  // console.log('file', file)
  // console.log('fileList', fileList)
  let index = picList.value.findIndex((item: any) => {
    return item.uid === file.uid
  })
  picList.value.splice(index, 1)
  uploadDisabled.value = picList.value.length >= 1
  dialogFormData.value.pic = ''
}
// 删除歌曲
const handleSongRemove = (file: any, fileList: any) => {
  let index = songList.value.findIndex((item: any) => {
    return item.uid === file.uid
  })
  songList.value.splice(index, 1)
  dialogFormData.value.url = ''
}
// 预览头像
const handlePicturePreview = (file: any) => {
  // console.log('file', file)
  preImgVisible.value = true
}
// 自动检索歌词
const autoLyric = async () => {
  if (!dialogFormData.value.name) {
    ElMessage.error('请先填写歌曲名')
    return
  }
  // 根据歌曲名找歌曲id
  const target = songDataAll.value.find((item: any) => {
    return item.name.includes(dialogFormData.value.name)
  })
  if (target) {
    alert('库中检索到了该歌曲')
    let res = await songFindLyricApi(target.id)
    // map:生成一个新数组，join:将数组元素连接形成字符串
    dialogFormData.value.lyric = res.data.map((item: any) => '[' + item.time + '] ' + item.lyric).join('\n')
    // for (let i = 0; i < res.data.length; i++){
    //   dialogFormData.value.lyric += '['+ res.data[i].time + ']' + res.data[i].lyric + '\n'
    // }
  } else {
    ElMessage.warning('库中尚未记录该歌曲')
  }
}
// 手动检索歌词【TODO】
const selfLyric = () => {
  ElMessage.warning('待完善功能，敬请期待！')
}
// 更改账号状态
const updateStatus = async(row:any)=>{
  row.status = row.status === '0' ? '1' : '0'
  await songSaveApi(row,0)
  ElMessage.success('修改账号状态成功')
  findBySearch()
}
// table选项发生变化时触发
const handleSelectionChange = (selections:any)=>{
  // console.log('选中的项：',selections)
  selecteList.value = selections
}
// 批量删除
const delBatch = async ()=>{
  if(selecteList.value.length===0){
    ElMessage.warning('请勾选您要删除的项')
    return
  }
  await songDelBatchApi(selecteList.value)
  ElMessage.success('批量删除成功')
  findBySearch()
  selecteList.value = []
}
// 取消选择
const cancelSelecte = ()=>{
  if(selecteList.value.length===0){
    ElMessage.warning('还未选择')
    return
  }
  selecteList.value = []
  tableRef.value.clearSelection()//取消表格中已勾选的选项
}
// 导出报表【TODO】
const exportReport = ()=>{
  if(selecteList.value.length===0){
    ElMessage.warning('请选择要导出的数据')
    return
  }
  // let ids = selecteList.value.map((item:any)=>item.id)
  // window.open('http://localhost:8080/api/song/export/'+ids+'?token='+getToken(),'_blank')
  ElMessage.warning('该功能待完善')
}
//批量导入【TODO】
const importBatch = ()=>{
  ElMessage.warning('该功能暂未开放，敬请期待！')
}
// 新增or修改弹窗确定
const submit = async () => {
  // await songSaveApi(dialogFormData.value,dialogFormData.value.cont)
  // ElMessage.success(dialogFormData.value.id ? '修改成功' : '添加成功')
  // dialogFormVisible.value = false
  // findBySearch()
  try {
    await songSaveApi(dialogFormData.value, dialogFormData.value.cont)
    ElMessage.success(dialogFormData.value.id ? '修改成功' : '添加成功')
    dialogFormVisible.value = false
    findBySearch()
  } catch (error: any) {
    if (error.msg === '该歌曲已存在，请勿重复添加') {
      ElMessageBox.confirm(
        '要添加的歌曲已存在，此操作将强制添加，是否继续？',
        'Warning', {
        confirmButtonText: '确定',
        cancelButtonText: '取消'
      }
      ).then(() => {
        ElMessage.success('操作成功，继续提交可强制添加')
        dialogFormData.value.cont = 1
      }).catch(() => {
        ElMessage.info('已取消操作')
      })
    }
  }
}
// 新增or修改弹窗取消
const cancel = () => {
  dialogFormVisible.value = false
  picList.value = []
  songList.value = []
}
// 编辑歌单
const editSongList = async (row:any) =>{
  songListFormData.value.songListId = ''
  songListVisible.value = true
  songListFormData.value.songName = row.name
  songListFormData.value.songId = row.id
  // 根据歌曲id检索歌单集合
  let res = await songListFindBySongIdApi(row.id)
  songListFormData.value.songListNames = res.data
}
// 添加歌单弹窗确定
const songListSubmit = async()=>{
  await listSongSaveApi(songListFormData.value)
  let row = {
    id:songListFormData.value.songId,
    name:songListFormData.value.songName
  }
  editSongList(row)
}
// 移除现有歌单
const removeSongList = (item:any)=>{
  ElMessageBox.confirm(
    '确定要将此歌曲从歌单中移除嘛，请确认','提示',{
      confirmButtonText:'确定',
      cancelButtonText:'取消',
      type:'warning'
    }
  ).then(async ()=>{
    // item.id:歌单id
    await listSongDeleteApi(songListFormData.value.songId, item.id)
    ElMessage.success('移除成功')
    let row = {
      id: songListFormData.value.songId,
      name: songListFormData.value.songName
    }
    editSongList(row)
  }).catch(()=>{
    ElMessage.info('取消移除')
  })
}
// 路由跳转到歌单歌曲管理
const songListSongDetail = (item:any)=>{
  router.push({
    path:'/songList2Song',
    query:{songListId:item.id}
  })
}
</script>

<style scoped lang="scss">
.container {
  .search {
    display: flex;
    flex-wrap: nowrap;

    .el-input {
      width: 200px;
      margin-right: 10px;
    }

    .el-select {
      width: 100px;
      margin-right: 10px;
    }
  }

  .table {
    margin: 15px 0;

    .el-switch {
      --el-switch-on-color: #13ce66;
      --el-switch-off-color: #ff4949;
    }

    // 限制歌词的显示格式
    .multiline-ellipsis {
      display: -webkit-box;
      /* 多行折叠支持 */
      -webkit-line-clamp: 3;
      /* 限制显示的行数 */
      -webkit-box-orient: vertical;
      /* 垂直排列子元素（多行） */
      overflow: hidden;
      /* 超出隐藏 */
      text-overflow: ellipsis;
      /* 超出用省略号 */
      line-height: 20px;
      /* 每行高度（可调） */
      max-height: 60px;
      /* 3行 * line-height */
    }
  }

  .pagination {
    display: flex;
    justify-content: center;
  }

  .dialog {

    .el-input,
    .el-select {
      width: 90%;
    }
  }
}

/* CSS */
.cell {
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}

// 深度选择器
.none-up ::v-deep(.el-upload--picture-card) {
  display: none;
}
</style>